package com.smartcommunity.service.village.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.smartcommunity.base.bean.ExceptionCode;
import com.smartcommunity.base.common.CacheMap;
import com.smartcommunity.bean.constant.Constant;
import com.smartcommunity.bean.entity.User;
import com.smartcommunity.bean.enumeration.ResultCode;
import com.smartcommunity.bean.enumeration.TagGroupEnum;
import com.smartcommunity.bean.model.Pager;
import com.smartcommunity.bean.model.Result;
import com.smartcommunity.dao.tag.TagDao;
import com.smartcommunity.dao.village.RealPowerOrgDao;
import com.smartcommunity.dao.village.VillageDao;
import com.smartcommunity.entity.people.RealPower;
import com.smartcommunity.entity.people.dto.AddRealPowerDto;
import com.smartcommunity.entity.people.dto.UpdateRealPowerDto;
import com.smartcommunity.entity.tag.ObjectTag;
import com.smartcommunity.entity.tag.Tag;
import com.smartcommunity.entity.village.OrganizationRealPower;
import com.smartcommunity.entity.village.OrganizationVillage;
import com.smartcommunity.entity.village.RealPeopleLabel;
import com.smartcommunity.entity.village.RealPowerOrg;
import com.smartcommunity.exception.BusinessException;
import com.smartcommunity.service.tag.TagService;
import com.smartcommunity.service.village.RealPowerOrgService;
import com.smartcommunity.utils.RegExUtils;
import com.smartcommunity.utils.StringUtils;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

import static org.apache.commons.lang3.StringUtils.length;

/**
 * @ClassName: RealPowerOrgServiceImpl
 * @Description: 实有力量维护
 * @author: minsheng
 * @Date: 2019/1/17 14:58
 * @Company:
 * @version V1.5.0
 */
@Service
public class RealPowerOrgServiceImpl implements RealPowerOrgService {
    private final RealPowerOrgDao realPowerOrgDao;

    private final VillageDao villageDao;

    @Autowired
    TagDao tagDao;
    @Autowired
    TagService tagService;

    @Autowired
    public RealPowerOrgServiceImpl(RealPowerOrgDao realPowerOrgDao, VillageDao villageDao) {
        this.realPowerOrgDao = realPowerOrgDao;
        this.villageDao = villageDao;
    }

    /**
     * 获取实有力量
     * @param id
     * @return
     */
    @Override
    public Result getRealPower(String id) {
        RealPower realPower =  realPowerOrgDao.getRealPower(id);
        return Result.ok(realPower);
    }

    /**
     * 新增实有力量
     * @param addRealPowerDto
     * @return
     */
    @Override
    @Transactional(value = "mysqlTransactionManager", rollbackFor = {BusinessException.class})
    public Result insertRealPower(AddRealPowerDto addRealPowerDto) {

        if(Constant.IDCARD_VALUE == Integer.parseInt(addRealPowerDto.getCredentialType())){
            if (!RegExUtils.isIdCardNo(addRealPowerDto.getCredentialNo())) {
                return Result.error(ResultCode.PEOPLE_CREDENTIALNO_ERROR);
            }
        }else{
            if (length(addRealPowerDto.getCredentialNo())>18) {
                return Result.error(ResultCode.PEOPLE_CREDENTIALNO_ERROR);
            }
        }

        //设置标签信息
        List<ObjectTag> tagList = new ArrayList<>();
        List<Integer> labels = addRealPowerDto.getLabels();
        for(Integer label : labels){
            ObjectTag  objectTag = new ObjectTag(addRealPowerDto.getCredentialNo(),null,label);
            tagList.add(objectTag);
        }
        if(!tagList.isEmpty()){
            tagDao.addObjectTag(tagList);
        }

        List<AddRealPowerDto> list = new ArrayList<>();
        addRealPowerDto.setGender();
        list.add(addRealPowerDto);
        realPowerOrgDao.insertRealPower(list);
        return Result.ok();
    }


    /**
     * 修改实有力量
     * @param updateRealPowerDto
     * @return
     */
    @Override
    @Transactional(value = "mysqlTransactionManager", rollbackFor = {BusinessException.class})
    public Result updateRealPower(UpdateRealPowerDto updateRealPowerDto) {
        //校验身份证号码是否存在
        Map<String,Object> param = new HashMap<>();
        param.put("id",updateRealPowerDto.getId());
        param.put("credentialType",updateRealPowerDto.getCredentialType());
        param.put("credentialNo",updateRealPowerDto.getCredentialNo());
        List<RealPower> lt = realPowerOrgDao.getRealPowerByNoSelf(param);
        if(CollectionUtils.isNotEmpty(lt)){
            return  Result.error(ResultCode.USER_UPDATE_PEOPLE_EXIST_ERROR);
        }

        //设置标签信息
        List<ObjectTag> tagList = new ArrayList<>();
        List<Integer> labels = updateRealPowerDto.getLabels();
        for(Integer label : labels){
            ObjectTag  objectTag = new ObjectTag(updateRealPowerDto.getCredentialNo(),null,label);
            tagList.add(objectTag);
        }
        if(!tagList.isEmpty()){
            //删除标签关联信息
            param = new HashMap<>();
            param.put("objectId",updateRealPowerDto.getCredentialNo());
            tagDao.deleteObjectTag(param);
            tagDao.addObjectTag(tagList);
        }

        List<UpdateRealPowerDto> list = new ArrayList<>();
        updateRealPowerDto.setGender();
        list.add(updateRealPowerDto);
        realPowerOrgDao.updateRealPower(list);
        return Result.ok();
    }

    @Transactional
    @Override
    public Result deleteRealPower(String ids) {
        List<RealPower> list = new ArrayList<>();
        List<ObjectTag> taglist = new ArrayList<>();
        String [] idArr = ids.split(",");
        for(String id :idArr){

            RealPower realPower = realPowerOrgDao.getRealPower(id);
            if(realPower != null ){
                String credentialNo = realPower.getCredentialNo();
                //实有力量关联标签
                ObjectTag objectTag = new ObjectTag(credentialNo,null,null);
                list.add(realPower);
                taglist.add(objectTag);
            }
        }
        if(list.isEmpty()){
            return Result.error(ResultCode.DATA_LOSE);
        }

        //删除实有力量
        realPowerOrgDao.deleteRealPower(list);

        //删除关联标签
        if(!taglist.isEmpty()) {
            tagDao.deleteObjectTagList(taglist);
        }

        return Result.ok();
    }

    /**
     * 批量入库实有力量统计
     * @param realPowerOrgs 实有力量统计列表
     */
    @Override
    public void addRealPowers(List<RealPowerOrg> realPowerOrgs) {
        realPowerOrgDao.addRealPowers(realPowerOrgs);
    }

    /**
     * 添加或修改实有力量
     * @param realPowerOrg
     */
    @Override
    public void addOrUpdateRealPower(RealPowerOrg realPowerOrg) {
        realPowerOrgDao.addOrUpdateRealPower(realPowerOrg);
    }

    /**
     * 根据指定的组织机构id查询该组织机构下的所有小区实有力量统计
     * @param param 请求参数
     * @return 实有力量统计
     */
    @Override
    public Pager<Object> getRealPowerStatisticsByParam(Map<String, Object> param) {
        return getOrganizationVillageByChildrenId(param);
    }

    /**
     * 获取实有力量记录总数
     * @return 记录数
     */
    @Override
    public Integer getRealPowerOrgCount() {
        return realPowerOrgDao.getRealPowerOrgCount();
    }
    @Override
    public Integer getRealPowerCount() {
        return realPowerOrgDao.getRealPowerCount();
    }

    /**
     * 按照树形组织机构获取各个层级的实有力量数据
     * @param param 请求参数
     * @return 组织机构数据列表
     */
    private Pager<Object> getOrganizationVillageByChildrenId(Map<String, Object> param) {
        List<Object> list = new ArrayList<>();
        List<OrganizationVillage> organizationList;
        Pager<Object> orgPageData = null;
        int pageNumber = (int) param.get("pageNumber");
        int pageSize = (int) param.get("pageSize");
        // 获取指定层级的直接子级
        Integer rootId = (Integer) param.get("rootId");
        if (rootId != null) {
            // 开启分页
            PageHelper.startPage(pageNumber, pageSize);
            organizationList = villageDao.listOrganizationVillageByChildrenId(rootId);

            // 如果存在子级则设置该级的实有力量求和数据，否则返回该级的小区实有力量数据
            if (organizationList != null && organizationList.size() > 0) {
                // 创建分页对象
                int count = (int) ((Page) organizationList).getTotal();
                orgPageData = new Pager<>(pageNumber, pageSize, count);

                for (OrganizationVillage organization : organizationList) {
                    OrganizationRealPower organizationRealPower = new OrganizationRealPower();
                    // 设置组织机构id
                    organizationRealPower.setId(organization.getId());
                    // 设置组织机构编码
                    organizationRealPower.setOrgCode(organization.getOrgCode());
                    // 设置组织机构名称
                    organizationRealPower.setOrgName(organization.getOrgName());
                    // 设置组织机构父级id
                    organizationRealPower.setParentId(organization.getParentId());

                    // 设置默认居委干部数量
                    organizationRealPower.setCadresCount(0);
                    // 设置默认保洁数量
                    organizationRealPower.setCleanCount(0);
                    // 设置默认保安数量
                    organizationRealPower.setCourierCount(0);
                    // 设置默认保绿数量
                    organizationRealPower.setGreenCount(0);
                    // 设置默认楼组长数量
                    organizationRealPower.setLzzCount(0);
                    // 设置默认警员数量
                    organizationRealPower.setPoliceCount(0);
                    // 设置默认保安数量
                    organizationRealPower.setSecurityCount(0);
                    // 设置默认志愿者数量
                    organizationRealPower.setVolunteerCount(0);

                    // 获取对应的实有力量数据
                    // 传入该组织机构id
                    param.put("rootId", organization.getId());
                    RealPowerOrg realPowerOrg = realPowerOrgDao.getRealPowerStatisticsGruopByRootId(param);
                    if (realPowerOrg != null) {
                        // 设置居委干部数量
                        organizationRealPower.setCadresCount(realPowerOrg.getCadresCount());
                        // 设置保洁数量
                        organizationRealPower.setCleanCount(realPowerOrg.getCleanCount());
                        // 设置保安数量
                        organizationRealPower.setCourierCount(realPowerOrg.getCourierCount());
                        // 设置保绿数量
                        organizationRealPower.setGreenCount(realPowerOrg.getGreenCount());
                        // 设置楼组长数量
                        organizationRealPower.setLzzCount(realPowerOrg.getLzzCount());
                        // 设置警员数量
                        organizationRealPower.setPoliceCount(realPowerOrg.getPoliceCount());
                        // 设置保安数量
                        organizationRealPower.setSecurityCount(realPowerOrg.getSecurityCount());
                        // 设置志愿者数量
                        organizationRealPower.setVolunteerCount(realPowerOrg.getVolunteerCount());
                    }

                    list.add(organizationRealPower);
                }
                orgPageData.setList(list);
            } else {
                // 开启分页
                PageHelper.startPage(pageNumber, pageSize);
                // 获取该级下的所有小区
                List<Object> vList = realPowerOrgDao.getRealPowerOrgs(param);
                // 创建分页对象
                int count = (int) ((Page) vList).getTotal();
                orgPageData = new Pager<>(pageNumber, pageSize, count);
                orgPageData.setList(vList);
            }
        }

        return orgPageData;
    }


    /**
     * @DESC：实有力量编辑  包含新增，查询，删除，修改
     *
     * @param list ：[{opr:"操作类型",data:[{key:'value'}]},{opr:"操作类型",data:{}}]
     * */
    @Override
    public Object updateRealPower(List list, User user){

        Map result = new HashMap(1);
        for (Object item : list){
            Map param  = (Map) item;

            if (param.get("opr")==null) {
                throw new BusinessException(20401, "操作类型不能为空");
            }
            String opr = (String) param.get("opr");
            Object temp = param.get("data");

            List res = new ArrayList();
            if (temp instanceof Map) {
                res = new ArrayList();
                res.add(temp);
            }else if(temp instanceof List) {
                res = (List) param.get("data");
            }
            if (res.size() == 0 && !opr.equals("query")) {
                throw new BusinessException(20403,"data不能为空");
            }
            Map map = (Map) temp;
            String credentialNo = map.get("credentialNo").toString();
            String villageCode = map.get("villageCode").toString();
            List<Integer> tagList = new ArrayList<>();
            if(StringUtils.isNotEmpty(param.get("tagList"))){
                tagList = (List<Integer>) param.get("tagList");
            }
            Map<String, Object> queryMap = new HashMap<>(2);
            queryMap.put("groupId","3");
            List<Tag> groupList = tagDao.getTagList(queryMap);
            String tagIds = "";
            for (Tag tg : groupList){
                tagIds += tg.getId()+",";
            }
            queryMap.clear();
            queryMap.put("objectId",credentialNo);
            if(tagIds.length() > 0) {
                queryMap.put("tagIds", tagIds.substring(0, tagIds.length() - 1));
            }
            switch (opr){
                case "add":
                    this.validate(res);
                    tagService.addObjectTag(credentialNo,villageCode,tagList);
                    result.put("add",this.realPowerOrgDao.insertRealPower(res));
                    break;
                case "delete":
                    tagDao.deleteObjectTag(queryMap);
                    result.put("delete",this.realPowerOrgDao.deleteRealPower(res));
                    break;
                case "update":
                    tagDao.deleteObjectTag(queryMap);
                    tagService.addObjectTag(credentialNo,villageCode,tagList);
                    result.put("update",this.realPowerOrgDao.updateRealPower(res));
                    break;
                default:
                    throw new BusinessException(20404,"未找到相应的处理");
            }
        }
        return result;
    }

    @Override
    public Result queryRealPower(Map<String, Object> param, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<RealPower> list = realPowerOrgDao.getRealPowers(param);
        param.clear();
        for (RealPower rp : list){
            param.put("objectId",rp.getCredentialNo());
            param.put("groupId", String.valueOf(TagGroupEnum.REWLPOWERPEOPLE.getValue()));
            List<Tag> tagList = tagDao.getObjectTag(param);
            rp.setTagList(tagList);
        }
        Pager page = new Pager(pageNum,pageSize, (int) ((Page)list).getTotal());
        page.setList(list);
        return Result.ok(page);
    }




    /**
     * @Description: 删除实有力量标签
     * @param: [credentialNo]
     * @return: int
     * @auther: minsheng
     * @date: 2019/5/17 13:53
     */
    public  void deleteLabel(List<Map> list){
        list.stream().forEach(item->{
            String labels = (String) item.getOrDefault("label","");
            String[] label = labels.split(",");
            Arrays.asList(label).forEach(temp->{
                Map map = new HashMap();
                map.put("label",temp);
                map.put("credentialNo",item.get("credentialNo"));
                realPowerOrgDao.deleteRealPowerLabelByLabel(map);
            });
        });
    }
    /**
     * @Description: 人员标签，先删除后插入(2019-5-10修改为标签不删除，新增标签继续插入)
     * @param: [list, flag]
     * @return: int
     * @author: minsheng
     * @date: 2019/1/17 14:55
     */
    public int updateLabel(List<Map> list,boolean...flag){
        List param = new ArrayList();
        List No = new ArrayList();
        list.stream().forEach(item->{
            if (item.get("credentialNo") == null) {
                throw new BusinessException(ExceptionCode.REALPOWER_NOTNULL_EXCEPTION_CODE, "身份编号不能为空");
            } else if (item.get("credentialType") == null) {
                throw new BusinessException(ExceptionCode.REALPOWER_NOTNULL_EXCEPTION_CODE,"身份编号类型不能为空");
            }else if(item.get("label") == null){
                throw new BusinessException(ExceptionCode.REALPOWER_NOTNULL_EXCEPTION_CODE,"人物标签不能为空");
            }

            String labels = (String) item.getOrDefault("label","");

            if (!labels.equals("")) {

                String[] label = labels.split(",");

                Arrays.asList(label).forEach(temp->{
                    Map map = new HashMap();
                    item.remove("label");
                    map.putAll(item);
                    map.put("label",temp);
                    RealPeopleLabel rp = realPowerOrgDao.getRealPoweLabel(map);
                    if(rp == null) {
                        param.add(map);
                    }
                });
            }
            No.add("'"+item.get("credentialNo")+"'");
        });
        int res = 0;
        if (param.size()!=0 && (flag.length ==0 || !flag[0])) {
            res += this.realPowerOrgDao.inserRealPowerLabel(param);
        }

        return res;
    }

    /**
     * @Description: 验证数据是否已经存在
     * @param: [param]
     * @return: void
     * @author: minsheng
     * @date: 2019/1/17 14:55
     */
    private void validate(List<Map> param){

        param.forEach(map -> {
           if( this.realPowerOrgDao.getRealPoweCount(map)>0){
               throw new BusinessException(20406, "该身份证已经存在");
           }
        });
    }
}
